<?php
namespace Fc;

use GuzzleHttp\Client;
use Ramsey\Uuid\Uuid;
use DateTime;
use DateTimeZone;

class Credentials {
    private $AK;
    private $SK;

    public function __construct($AK, $SK) {
        $this->AK = $AK;
        $this->SK = $SK;
    }

    public function doCTAPIRequest($request) {
        $reqURL = $request->url;
        $method = $request->method;
        $headers = $request->headers;
        $data = $request->data ?? [];
        $query = $request->query ?? [];

        $queryStr = $this->getCTAPISortedQueryString($query);
        if ($queryStr !== '') {
            $reqURL .= '?' . $queryStr;
        }

        $reqBody = '';
        if (!empty($data)) {
            if ($headers['Content-Type'] === 'application/json') {
                $reqBody = json_encode($data);
                $headers['Content-Type'] = 'application/json; charset=utf-8';
            } else {
                $reqBody = http_build_query($data);
                $headers['Content-Type'] = 'application/x-www-form-urlencoded';
            }
        }

        unset($headers['regionId']);
        $uuid = $this->generateUUID();
        $timezone = new DateTimeZone('Asia/Shanghai');
        $eopDate = (new DateTime('now', $timezone))->format('Ymd\THis') . 'Z';
        $authorization = $this->getCTAPIAuthorization($queryStr, $reqBody, $uuid, $this->AK, $this->SK, $eopDate);

        $config = [
            'headers' => array_merge($headers, [
                'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/110.0',
                'Ctyun-Eop-Request-Id' => $uuid,
                'Eop-Date' => $eopDate,
                'Eop-Authorization' => $authorization,
                'Content-Length' => strlen($reqBody),
            ]),
            'body' => $reqBody,
            'verify' => false, // 禁用SSL证书验证，仅用于测试环境
        ];

        $client = new Client();
        $response = $client->request($method, $reqURL, $config);
        if ($response->getStatusCode() === 200) {
            $rsp = $response->getBody()->getContents();
            printf("ctapi response: %s\n", $rsp);
            return $rsp;
        }
        throw new \HttpResponseException("状态码非200", $response->getStatusCode());
    }

    private function generateUUID() {
        return Uuid::uuid4()->toString();
    }

    private function getCTAPISortedQueryString($query): string {
        ksort($query);

        // 使用http_build_query生成查询字符串
        $queryString = http_build_query($query);

        // 可选：将空格编码从+改为%20以符合更严格的URL规范
        // 构建URL查询字符串格式
        return str_replace('+', '%20', $queryString);
    }

    private function getCTAPIAuthorization($query, $body, $uuid, $ak, $sk, $timestamp): string {
        $hashedRequestBody = hash('sha256', $body); // 已对hash结果进行hex digest处理
        $signature = "ctyun-eop-request-id:$uuid\neop-date:$timestamp\n\n$query\n$hashedRequestBody";
        $ktime = $this->signatureMethod($sk, $timestamp, 'sha256');
        $kak = $this->signatureMethod($ktime, $ak, 'sha256');
        $kdate = $this->signatureMethod($kak, substr($timestamp, 0, 8), 'sha256');
        $signaSha256 = $this->signatureMethod($kdate, $signature, 'sha256');
        $base64Signa = base64_encode($signaSha256);
        $signHeader = "$ak Headers=ctyun-eop-request-id;eop-date Signature=$base64Signa";
        return $signHeader;
    }

    private function signatureMethod($key, $message, $algorithm): string {
        // 返回未base64编码的二进制哈希值
        return hash_hmac($algorithm, $message, $key, true);
    }
}
